﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<ctype.h>
#include<assert.h>





//int main()
//{
//	int a[] = { 1,2,3,4 };
//	printf("%zd\n", sizeof(a));//16    sizeof(数组名)的场景
//	printf("%zd\n", sizeof(a + 0));//8 a是首元素地址类型int*，a+0还是首元素地址，是地址大小就是4/8
//	printf("%zd\n", sizeof(*a));//4  a是首元素的地址，*a就是首元素，大小就是4个字节
//	printf("%zd\n", sizeof(a + 1));//8 a是首元素地址，类型是int*，a+1就三句话hi跳过一个整形，a+1就是第二个元素的地址，4/8
//	printf("%zd\n", sizeof(a[1]));//4  a[1]就是第二个元素，大小4个字节
//	printf("%zd\n", sizeof(&a));//8   &a是数组的地址，数组的地址也是地址，是地址大小就是4/8个字节
//	printf("%zd\n", sizeof(*&a));//16  访问的是数组，数组的大小16
//	printf("%zd\n", sizeof(&a + 1));//8 &a+1就是跳过整个数组后的那个位置的地址，是地址就是4/8个字节
//	printf("%zd\n", sizeof(&a[0]));//8  首元素的地址，大小4/8个字节
//	printf("%zd\n", sizeof(&a[0] + 1));//8 数组第二个元素的地址，大小是4/8个字节
//	return 0;
//}


 
//int main()
//{
//	char arr[] = { 'a','b','c','d','e','f' };
//	printf("%zd\n", sizeof(arr));//6
//	printf("%zd\n", sizeof(arr + 0));//8
//	printf("%zd\n", sizeof(*arr));//1;
//	printf("%zd\n", sizeof(arr[1]));//1
//	printf("%zd\n", sizeof(&arr));//8
//	printf("%zd\n", sizeof(&arr + 1));//8
//	printf("%zd\n", sizeof(&arr[0] + 1));//8
//	return 0;
//}




//int main()
//{
//	char arr[] = { 'a','b','c','d','e','f' };
//	printf("%zd\n", strlen(arr));
//	printf("%zd\n", strlen(arr + 0));
//	printf("%zd\n", strlen(*arr));
//	printf("%zd\n", strlen(arr[1]));
//	printf("%zd\n", strlen(&arr));
//	printf("%zd\n", strlen(&arr + 1));
//	printf("%zd\n", strlen(&arr[0] + 1));
//	return 0;
//}




//int main()
//{
//	char arr[] = "abcdef";
//	printf("%zd\n", sizeof(arr));//7
//	printf("%zd\n", sizeof(arr + 0));//8
//	printf("%zd\n", sizeof(*arr));//1
//	printf("%zd\n", sizeof(arr[1]));//1
//	printf("%zd\n", sizeof(&arr));//8
//	printf("%zd\n", sizeof(&arr + 1));//8
//	printf("%zd\n", sizeof(&arr[0] + 1));//8
//	return 0;
//}



//int main()
//{
//	char arr[] = "abcdef";
//	printf("%d\n", strlen(arr));
//	printf("%d\n", strlen(arr + 0));
//	printf("%d\n", strlen(*arr));
//	printf("%d\n", strlen(arr[1]));
//	printf("%d\n", strlen(&arr));
//	printf("%d\n", strlen(&arr + 1));
//	printf("%d\n", strlen(&arr[0] + 1));
//	return 0;
//}



//int main()
//{
//	char* p = "abcdef";
//	printf("%zd\n", sizeof(p));//8
//	printf("%zd\n", sizeof(p + 1));//8
//	printf("%zd\n", sizeof(*p));//1
//	printf("%zd\n", sizeof(p[0]));//1
//	printf("%zd\n", sizeof(&p));//8
//	printf("%zd\n", sizeof(&p + 1));//8
//	printf("%zd\n", sizeof(&p[0] + 1));//8
//	return 0;
//}



//int main()
//{
//	char* p = "abcdef";
//	printf("%zd\n", strlen(p));
//	printf("%zd\n", strlen(p + 1));
//	printf("%zd\n", strlen(*p));
//	printf("%zd\n", strlen(p[0]));
//	printf("%zd\n", strlen(&p));
//	printf("%zd\n", strlen(&p + 1));
//	printf("%zd\n", strlen(&p[0] + 1));
//	return 0;
//}





//int main()
//{
//	int a[3][4] = { 0 };
//	printf("%zd\n", sizeof(a));//48
//	printf("%zd\n", sizeof(a[0][0]));//4
//	printf("%zd\n", sizeof(a[0]));//16
//	printf("%zd\n", sizeof(a[0] + 1));//8
//	printf("%zd\n", sizeof(*(a[0] + 1)));//4
//	printf("%zd\n", sizeof(a + 1));//8
//	printf("%zd\n", sizeof(*(a + 1)));//16
//	printf("%zd\n", sizeof(&a[0] + 1));//8
//	printf("%zd\n", sizeof(*(&a[0] + 1)));//16
//	printf("%zd\n", sizeof(*a));//16
//	printf("%zd\n", sizeof(a[3]));//16
//	return 0;
//}


//1. sizeof(数组名)，这⾥的数组名表⽰整个数组，计算的是整个数组的⼤⼩。
//2. & 数组名，这⾥的数组名表⽰整个数组，取出的是整个数组的地址。
//3. 除此之外所有的数组名都表⽰⾸元素的地址。


//int main()
//{
//	int a[5] = { 1, 2, 3, 4, 5 };
//	int* ptr = (int*)(&a + 1);
//	printf("%d,%d", *(a + 1), *(ptr - 1));//2,5
//	return 0;
//}



//在X86环境下 
//假设结构体的⼤⼩是20个字节 
//struct Test
//{
//	int Num;
//	char* pcName;
//	short sDate;
//	char cha[2];
//	short sBa[4];
//}*p = (struct Test*)0x100000;
//int main()
//{
//	printf("%p\n", p + 0x1);
//	printf("%p\n", (unsigned long)p + 0x1);
//	printf("%p\n", (unsigned int*)p + 0x1);
//	return 0;
//}



//int main()
//{
//	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
//	int* p;
//	p = a[0];
//	printf("%d", p[0]);//1
//	return 0;
//}


//int main()
//{
//	int a[5][5];
//	int(*p)[4];
//	p = a;
//	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);//FFFFFFFC,-4
//	return 0;
//}



//int main()
//{
//	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//	int* ptr1 = (int*)(&aa + 1);
//	int* ptr2 = (int*)(*(aa + 1));
//	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10,5
//	return 0;
//}


//int main()
//{
//	char* a[] = { "work","at","alibaba" };
//	char** pa = a;
//	pa++;
//	printf("%s\n", *pa);//at
//	return 0;
//}



//int main()
//{
//	char* c[] = { "ENTER","NEW","POINT","FIRST" };
//	char** cp[] = { c + 3,c + 2,c + 1,c };
//	char*** cpp = cp;
//	printf("%s\n", **++cpp);//POINT
//	printf("%s\n", *-- * ++cpp + 3);//ER
//	printf("%s\n", *cpp[-2] + 3);//ST
//	printf("%s\n", cpp[-1][-1] + 1);//EW
//	return 0;
//}




/*int main()
{
	int i = 0;
	char str[] = "Test String.\n";
	char c;
	while (str[i])
	{
		c = str[i];
		if (islower(c))
			c -= 32;
		putchar(c);
		i++;
	}
	return 0;
}*/



//int main()
//{
// const char* str1 = "abcdef";
// const char* str2 = "bbb";
// if(strlen(str2)-strlen(str1)>0)
// {
// printf("str2>str1\n");
// } 
// else
// {
// printf("srt1>str2\n");
// }
// return 0;
//}


//计数器的版本
//size_t my_strlen(const char* s)
//{
//	assert(s);
//	int count = 0;
//	while (*s != '\0');
//	{
//		count++;
//		s++;
//	}
//	return count;
//}
//int main()
//{
//	char arr[] = "abcdef";
//	size_t len = my_strlen(arr);
//	printf("%zd\n", len);
//	return 0;
//}


//不能创建临时变量计数器  递归

//int my_strlen(const char* str)
//{
//	assert(str);
//	if (*str == '\0')
//		return 0;
//	else
//		return 1 + my_strlen(str + 1);
//}
//int main()
//{
//	char arr[] = "abcdef";
//	size_t len = my_strlen(arr);
//	printf("%zd\n", len);
//	return 0;
//}



//strcpy的使⽤和模拟实现
//• 源字符串必须以 '\0' 结束。
//• 会将源字符串中的 '\0' 拷⻉到⽬标空间。
//• ⽬标空间必须⾜够⼤，以确保能存放源字符串。
//• ⽬标空间必须可修改。
//• 学会模拟实现。

//char* my_strcpy(char* dest, const char* src)
//{
//	char* ret = dest;
//	assert(dest != NULL);
//	assert(src != NULL);
//
//	while ((*dest++ = *src++))
//	{
//		;
//	}
//	return ret;
//}
//int main()
//{
//	char arr1[] = "hello bit";
//	char arr2[20] = "xxxxxxxxxxxxx";
//	my_strcpy(arr2, arr1);
//	printf("%s\n", arr2);
//}


//strcat的使⽤和模拟实现
//• 源字符串必须以 '\0' 结束。
//• ⽬标字符串中也得有 \0 ，否则没办法知道追加从哪⾥开始。
//• ⽬标空间必须有⾜够的⼤，能容纳下源字符串的内容。
//• ⽬标空间必须可修改。
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest)
	{
		dest++;
	}
	while ((*dest++ = *src++))
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[] = "hello bit";
	char arr2[20] = { 0 };
	my_strcat(arr2, arr1);
	printf("%s\n", arr2);
}






























